--
-- Author: sg
-- Date: 2014-06-27 16:05:30
-- 工具，全局函数

function table.clone(st, deep)
    deep = deep or false
    local tab = {}
    if true == deep then
        tab = clone(st)
    else
        for k, v in pairs(st or {}) do
            tab[k] = v
        end
    end
    return tab
end

-- 按func返回true删除array里面指定项，返回删除个数
function table.removebyfunc(array, func, removeall)
    local c, i, max = 0, 1, #array
    while i <= max do
        if func and func(array[i]) then
            table.remove(array, i)
            c = c + 1
            i = i - 1
            max = max - 1
            if not removeall then break end
        end
        i = i + 1
    end
    return c
end


-- tab2连接到tab1后面
function table.attach(tab1, tab2)
    for i, v in ipairs(tab2 or {}) do
        table.insert(tab1, v)
    end
    return tab1
end

--从table中随机几个出来
--tab 数组
--cnt 随机数量（不填为#tab, 最大是#tab）
function table.randomCnt(tab, cnt)
    cnt = cnt or #tab
    if cnt > #tab then cnt = #tab end
    local tabCopy = table.clone(tab)
    
    local ret = {}
    while #ret < cnt do
        local index = math.random(1, #tabCopy)
        table.insert(ret, tabCopy[index])
        table.remove(tabCopy, index)
    end
    return ret
end

--tab 数组倒序 
function table.DESC(tab)
    local len = #tab
    local ret = {}
    for i,v in ipairs(tab) do
        if i <= (len+1)/2 then
            ret[i] = tab[len+1-i]
            ret[len+1-i] = v
        end
    end
    return ret
end

--截取数组，返回新的数组
function table.sub(tab, startIdx, endIdx, step)
    startIdx = startIdx or 1
    endIdx = endIdx or #tab
    step = step or 1
    local ret = {}
    for i=startIdx,endIdx,step do
        if tab[i] then
            table.insert(ret, tab[i])
        end
    end
    return ret
end

--tab元素和
function table.sum(tab)
    local ret = 0
    for k, v in pairs(tab or {}) do
        ret = ret + tonumber(v) or 0
    end
    return ret
end

--tab2中的值替换tab1中相同key的值,没有的新建
function table.reset(tab1, tab2)
    for k, v in pairs(tab2 or {}) do
        tab1[k] = v
    end
    return tab1
end

--为数组tab1顺序添加特定的key
function table.setKeys(tab1, keys)
    local ret = {}
    for i,v in ipairs(tab1) do
        ret[keys[i]] = v
    end
    return ret
end

function table.tonumber(tab)
    for key,value in pairs(tab) do
        tab[key] = tonumber(value)
    end
    return tab
end

--isFirst=true,插入到前面，isFirst=false,插入到后面，
function table.insertUnique(tab, value, isFirst)
    isFirst = isFirst or false
    for k,v in pairs(tab) do
        if v == value then
            return tab
        end
    end
    if isFirst then
        table.insert(tab, 1, value)
    else
        table.insert(tab, value)
    end
    return tab
end

--比较两个table的值是否相等，只支持lua的table，不支持c++对象，不支持class创建对象
-- depth 不需要传
function table.valueEqual(tabA, tabB, depth)
    depth = depth or 0
    if depth >= 5 then
        print("table.valueEqual depth can't > 5")
        return false
    end
    if (type(tabA) == 'table') and (type(tabB) == 'table') then
        if (#tabA ~= #tabB) then
            return false
        end
        local k,v
        for k,v in pairs(tabA) do
            if not table.valueEqual(v, tabB[k], depth+1) then
                return false
            end
        end
        for k,v in pairs(tabB) do
            if not table.valueEqual(v, tabA[k], depth+1) then
                return false
            end
        end
        return true
    elseif type(tabA) ~= type(tabB) then
        return false
    elseif tabA == tabB then
        return true
    end
    return false
end

--两个table相加，只处理table下都是单层且值是namber型
function table.add(tabA, tabB)
    local a_keys = table.keys(tabA)
    local b_keys = table.keys(tabB)
    if table.getn(a_keys) == 0 then
        return tabB
    end
    if table.getn(b_keys) == 0 then
        return tabA
    end
    local ret = {}
    for _,v in ipairs(b_keys) do
        table.insertUnique(a_keys, v)
    end
    for _, key in pairs(a_keys) do
        local va = tabA[key]
        local vb = tabB[key]
        if nil == va then
            ret[key] = vb
        elseif nil == vb then
            ret[key] = va
        else
            ret[key] = va + vb
        end
    end
    return ret
end
